﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CrazyReader.Core.Crawl;
using NSoup.Nodes;
using System.IO;

namespace PuzzleCrawler
{
    public class PuzzleCrawlTask : WebTaskBase
    {
        public const String Url = "http://www.puzzle8.com/cross/cross.asp?recordId={0}";
        public const String Encoding = "gb2312";
        public const String EmptyWord = "a";

        public int Id { get; set; }
        public String Path { get; set; }

        public override void OnStart()
        {
            base.OnStart();

            BeginGetResponse(String.Format(Url, Id), Encoding, doc =>
            {
                String html = doc.Html();
                //int rowCount = GetNum(html, "var rowNum");
                //int colCount = GetNum(html, "var colNum");
                String[] answer = GetAnswer(html);
                //只做10*10的
                if (answer.Length == 100)
                {
                    List<MapDef> map = ProcessMap(answer);
                    List<WordDefine> words = new List<WordDefine>();
                    var tables = doc.Select("table[width=100%][border=0][cellspacing=1]");
                    if (tables != null && tables.Count == 2)
                    {
                        foreach (var table in tables)
                        {
                            var trs = table.Select("td");
                            if (trs != null && trs.Count > 0)
                            {
                                var header = trs[0].Text();
                                if (header.Contains("横"))
                                {
                                    //横向处理
                                    for (int i = 1; i < trs.Count; i++)
                                    {
                                        WordDefine def = new WordDefine();
                                        def.IsHorizal = true;
                                        String text = trs[i].Text();
                                        int index = text.IndexOf('.');
                                        if (index != -1)
                                        {
                                            def.Tip = text.Substring(index + 1).Trim();
                                        }
                                        int wordIndex = GetIndex(trs[i]);
                                        def.ZhongWen = GetWordRow(map, wordIndex, words.Count);
                                        words.Add(def);
                                    }
                                }
                                else
                                {
                                    //纵向处理
                                    for (int i = 1; i < trs.Count; i++)
                                    {
                                        WordDefine def = new WordDefine();
                                        def.IsHorizal = false;
                                        String text = trs[i].Text();
                                        int index = text.IndexOf('.');
                                        if (index != -1)
                                        {
                                            def.Tip = text.Substring(index + 1).Trim();
                                        }
                                        int wordIndex = GetIndex(trs[i]);
                                        def.ZhongWen = GetWordCol(map, wordIndex, words.Count);
                                        words.Add(def);
                                    }
                                }
                            }
                        }

                        OutPut(words, map);
                    }
                }
            });
        }

        private void OutPut(List<WordDefine> words, List<MapDef> map)
        {
            using (StreamWriter sw = new StreamWriter(Path))
            {
                sw.WriteLine(words.Count);
                foreach (var word in words)
                {
                    //TODO 在这里处理拼音缩写
                    sw.WriteLine(String.Format("{0}--{1}--{2}", word.PinYin, word.ZhongWen, word.Tip));
                }

                foreach (var cell in map)
                {
                    if (!cell.IsEmpty)
                    {
                        //x,y,横向词index,横向字index,竖向词index,竖向字index
                        sw.WriteLine(String.Format("{0},{1},{2},{3},{4},{5}", cell.Row, cell.Col,
                            cell.HIndex == MapDef.EmptyIndex ? "N" : cell.HIndex.ToString(),
                            cell.HWordIndex == MapDef.EmptyIndex ? "N" : cell.HWordIndex.ToString(),
                             cell.VIndex == MapDef.EmptyIndex ? "N" : cell.VIndex.ToString(),
                              cell.VWordIndex == MapDef.EmptyIndex ? "N" : cell.VWordIndex.ToString()));
                    }
                }
            }
        }

        private List<MapDef> ProcessMap(String[] answers)
        {
            List<MapDef> map = new List<MapDef>();

            for (int row = 0; row < 10; row++)
            {
                for (int col = 0; col < 10; col++)
                {
                    MapDef def = new MapDef();
                    def.Row = row;
                    def.Col = col;
                    def.Word = answers[row * 10 + col];
                    def.IsEmpty = def.Word == EmptyWord;
                    map.Add(def);
                }
            }

            return map;
        }

        /// <summary>
        /// 获得纵向的词，结束为a
        /// </summary>
        /// <param name="map"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private String GetWordCol(List<MapDef> map, int index, int wordIndex)
        {
            String word = "";
            int row = index / 10;
            int col = index % 10;
            for (int i = row; i < 10; i++)
            {
                var cell = map[i * 10 + col];
                if (!cell.IsEmpty)
                {
                    cell.VIndex = wordIndex;
                    cell.VWordIndex = i - row;
                    word += cell.Word;
                }
                else
                    break;
            }
            return word;
        }

        /// <summary>
        /// 获得横向的词，结束为a
        /// </summary>
        /// <param name="map"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private String GetWordRow(List<MapDef> map, int index, int wordIndex)
        {
            String word = "";
            int row = index / 10;
            int col = index % 10;
            for (int i = col; i < 10; i++)
            {
                var cell = map[row * 10 + i];
                if (!cell.IsEmpty)
                {
                    cell.HIndex = wordIndex;
                    cell.HWordIndex = i - col;
                    word += cell.Word;
                }
                else
                    break;
            }
            return word;
        }

        private int GetIndex(Element node)
        {
            String value = node.Attr("onclick").Replace("javascript:handleTipTd2(", "").Replace(");", "");
            return Convert.ToInt32(value);
        }

        private String[] GetAnswer(String text)
        {
            int startIndex = text.IndexOf("var crossAnswerStr");
            int endIndex = text.Substring(startIndex).IndexOf(';');
            String value = text.Substring(startIndex, endIndex);
            return value.Replace("var crossAnswerStr=\"", "").Replace("\"", "").Split('|');
        }

        private int GetNum(String text, String key)
        {
            int startIndex = text.IndexOf(key);
            int endIndex = text.Substring(startIndex).IndexOf(';');
            String value = text.Substring(startIndex, endIndex);
            return Int32.Parse(value.Split('=')[1].Trim());
        }
    }
}
